﻿using System;
using System.Collections.Generic;
using System.Linq;
using Medianamik.Core;
using Medianamik.Core.DAL.Repositories;
using Medianamik.Core.Interfaces;

namespace Medianamik.Client.DAL
{
    public class NodeMapper
    {
        private readonly INodeRepository _nodeRepository;
        private readonly INodeTypeRepository _nodeTypeRepository;

        public NodeMapper(INodeRepository nodeRepository, 
                          INodeTypeRepository nodeTypeRepository)
        {
            _nodeRepository = nodeRepository;
            _nodeTypeRepository = nodeTypeRepository;
        }

        public INodeWrapper MapNode(IMedianamikDTO dto)
        {
            var nodeToSave = GetNodeToSave(dto);

            //Ne pas faire nodeToSave.NodeType --> Ne respecte pas le Repository Pattern
            //TODO: S'assurer que NodeType.Properties n'est pas lazy loaded

            MapProperties(dto, _nodeTypeRepository.GetById(dto.TypeId), nodeToSave);
            return nodeToSave;
        }

        protected virtual INodeWrapper GetNodeToSave(IMedianamikDTO dto)
        {
            return _nodeRepository.GetExistingNode(dto) ?? _nodeRepository.NewNode(dto);
        }

        protected virtual void MapProperties(IMedianamikDTO dto, NodeType nodeType, INodeWrapper nodeToSave)
        {
            foreach (var propertyName in GetNodeTypePropertyNames(nodeType))
            {
                var propertyInfo = dto.GetType().GetProperty(propertyName);
                if(propertyInfo != null)
                    nodeToSave.InnerNode[dto.CultureName][propertyName].SetValue(propertyInfo.GetValue(dto, null));
            }
        }

        protected virtual IEnumerable<string> GetNodeTypePropertyNames(NodeType nodeType)
        {
            
            return nodeType.GetAllProperties().Select(p => p.Name);
        }
    }
}
